function varargout = inverseKineDiff(robot,T,q0,eps)
    % 超冗余机械臂逆解(微分法)
    % robot：机器人SerialLink对象
    % T：目标位姿
    % q0：初始位置(猜测值)
    % eps：精度要求
    % lrm：步长最大值(不同机器人不一定相同)
    % lrn：步长最小值(不同机器人不一定相同)
    % max_iter：最大迭代次数(不同机器人不一定相同)
    % % 优化算法得出最佳值
    % lrm = 1.46898882700899;
    % lrn = 1.35784648585965;
    % max_iter = 550.197344627676;
    lrm = 0.2;
    lrn = 0.15;
    max_iter = 500;
    if 0 >= eps
        disp(eps)
        error("eps input error")
    end
    q_k = q0;
    T_k = robot.fkine(q_k);
    iter = 0;
    err_log = [];
    % 逆雅可比法
    while iter < max_iter
        % 齐次矩阵微动
        DELTA = T_k.T\(T.T - T_k.T);
        % 末端矩阵微动
        dV = [DELTA(1,4);DELTA(2,4);DELTA(3,4);DELTA(3,2);DELTA(1,3);DELTA(2,1)];
        % 雅可比矩阵
        J_k = robot.jacob0(q_k);
        % 余弦变化学习率
        lr = lrn + 0.5*(lrm-lrn)*(1+cos(iter/max_iter*pi));
        % 更新q
        dq =  pinv(J_k)*dV;
        q_k = q_k + lr*dq';
        q_k = jlim(q_k,robot.qlim);% 关节限位
        iter = iter + 1;
        % 计算误差
        T_k = robot.fkine(q_k);
        err = norm(Trans2X(T_k)-Trans2X(T),2);
        if err < eps% 误差满足条件
            break
        end
        err_log = [err_log;err];
    end
    % if iter >= max_iter
    %     warning("达到最大迭代次数");
    % end
    if nargout == 1
        varargout{1} = q_k;
    elseif nargout == 2
        varargout{1} = q_k;
        varargout{2} = iter;
    elseif nargout == 3
        varargout{1} = q_k;
        varargout{2} = iter;
        varargout{3} = err_log;
    else
        error('Too many output argment!')
    end
    % 齐次变换矩阵转换到末端位置最小表达
    function X = Trans2X(T)
        X = zeros(6,1);
        X(1:3) = T.t;
        eular = rotm2eul([T.n T.o T.a],'zyx');
        X(4:6) = eular'; 
    end
    % 关节限位
    function q = jlim(q,qlim)
        % size(qlim) = (n,2);
        % 向量格式统一
        if any(size(q) ~= size(qlim(:,1)))
            qmax = qlim(:,2)';
            qmin = qlim(:,1)';
        else
            qmax = qlim(:,2);
            qmin = qlim(:,1);
        end
        % 大小限制
        index = q > qmax;
        q(index) = qmax(index);
        index = q < qmin;
        q(index) = qmin(index);
    end
end